package com.ruoyi.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.dto.MsgTemplatePreviewDTO;
import com.ruoyi.system.entity.MsgTemplateDO;
import com.ruoyi.system.entity.MsgPushTaskDO;
import com.ruoyi.system.mapper.MsgTemplateMapper;
import com.ruoyi.system.mapper.MsgPushTaskMapper;
import com.ruoyi.system.mapper.ProjectMsgTemplateMapper;
import com.ruoyi.system.service.MsgTemplateService;
import com.ruoyi.system.service.ProjectMsgTemplateAdminService;
import com.ruoyi.system.service.ProjectMsgTemplateService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

import java.util.List;
import java.util.Map;

@Service
public class MsgTemplateServiceImpl extends ServiceImpl<MsgTemplateMapper, MsgTemplateDO> implements MsgTemplateService {

    @Resource
    private MsgPushTaskMapper msgPushTaskMapper;

    @Resource
    private ProjectMsgTemplateMapper projectMsgTemplateMapper;

    @Resource
    private ProjectMsgTemplateService projectMsgTemplateService;


    @Override
    public Long createTemplate(MsgTemplateDO dto) {
        createCheck(dto);
        // 默认值
        if (dto.getStatus() == null) {
            dto.setStatus(1);
        }
        if (dto.getNeedSignature() == null) {
            dto.setNeedSignature(0);
        }
        if (dto.getExpireDays() == null) {
            dto.setExpireDays(7);
        }
        save(dto);
        if (!dto.getProjectIds().isEmpty()) {
            for (Long projectId : dto.getProjectIds()) {
                projectMsgTemplateService.bind(projectId, dto.getId(), dto.getType(), SecurityUtils.getUsername());
            }
        }
        return dto.getId();
    }

    private void createCheck(MsgTemplateDO dto) {
        if (dto == null) {
            throw new ServiceException("参数为空");
        }
        if (dto.getName() == null || dto.getName().trim().isEmpty()) {
            throw new ServiceException("模板名称不能为空");
        }
        if (dto.getType() == null) {
            throw new ServiceException("消息类型不能为空");
        }
        if (dto.getTitle() == null || dto.getTitle().trim().isEmpty()) {
            throw new ServiceException("消息标题不能为空");
        }
        if (dto.getContent() == null || dto.getContent().trim().isEmpty()) {
            throw new ServiceException("模板内容不能为空");
        }
        // 重名校验（同type）
        int cnt = (int) count(new LambdaQueryWrapper<MsgTemplateDO>()
                .eq(MsgTemplateDO::getType, dto.getType())
                .eq(MsgTemplateDO::getName, dto.getName())
                .eq(MsgTemplateDO::getIsDeleted, 0));
        if (cnt > 0) {
            throw new ServiceException("同类型模板名称已存在");
        }
    }

    @Override
    public boolean updateTemplate(MsgTemplateDO dto) {
        MsgTemplateDO old = getById(dto.getId());
        if (old == null) {
            throw new ServiceException("模板不存在");
        }
        // 重名校验
        int cnt = (int) count(new LambdaQueryWrapper<MsgTemplateDO>()
                .eq(MsgTemplateDO::getType, dto.getType())
                .eq(MsgTemplateDO::getName, dto.getName())
                .ne(MsgTemplateDO::getId, dto.getId())
                .eq(MsgTemplateDO::getIsDeleted, 0));
        if (cnt > 0) {
            throw new ServiceException("同类型模板名称已存在");
        }

//        if (!dto.getProjectIds().isEmpty()) {
//            for (Long projectId : dto.getProjectIds()) {
//                projectMsgTemplateService.
//            }
//        }

        return updateById(dto);
    }

    @Override
    public boolean changeStatus(Long id, Integer status) {
        MsgTemplateDO t = getById(id);
        if (t == null) throw new ServiceException("模板不存在");
        t.setStatus(status);
        return updateById(t);
    }

    @Override
    public Long copyTemplate(Long id, String newName) {
        MsgTemplateDO t = getById(id);
        if (t == null) throw new ServiceException("模板不存在");
        if (newName == null || newName.trim().isEmpty()) throw new ServiceException("新模板名称不能为空");
        int cnt = (int) count(new LambdaQueryWrapper<MsgTemplateDO>()
                .eq(MsgTemplateDO::getType, t.getType())
                .eq(MsgTemplateDO::getName, newName)
                .eq(MsgTemplateDO::getIsDeleted, 0));
        if (cnt > 0) throw new ServiceException("同类型模板名称已存在");
        MsgTemplateDO n = new MsgTemplateDO();
        n.setName(newName);
        n.setType(t.getType());
        n.setTitle(t.getTitle());
        n.setContent(t.getContent());
        n.setNeedSignature(t.getNeedSignature());
        n.setExpireDays(t.getExpireDays() == null ? 7 : t.getExpireDays());
        n.setStatus(t.getStatus() == null ? 1 : t.getStatus());
        save(n);
        return n.getId();
    }

    @Override
    public String previewContent(Long templateId, Map<String, Object> vars) {
        MsgTemplateDO t = getById(templateId);
        if (t == null) throw new ServiceException("模板不存在");
        return render(t.getContent(), vars);
    }

    @Override
    public String previewContent(MsgTemplatePreviewDTO previewDTO) {
        if (previewDTO == null || previewDTO.getTemplateId() == null) {
            throw new ServiceException("模板ID不能为空");
        }
        return previewContent(previewDTO.getTemplateId(), previewDTO.getVars());
    }

    @Override
    public List<MsgTemplateDO> listByTypeAndStatus(Integer type, Integer status) {
        LambdaQueryWrapper<MsgTemplateDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MsgTemplateDO::getIsDeleted, 0);
        if (type != null) {
            wrapper.eq(MsgTemplateDO::getType, type);
        }
        if (status != null) {
            wrapper.eq(MsgTemplateDO::getStatus, status);
        }
        wrapper.orderByDesc(MsgTemplateDO::getCreateTime);
        List<MsgTemplateDO> list = list(wrapper);
        for (MsgTemplateDO msgTemplateDO : list) {
            msgTemplateDO.setProjectIds(projectMsgTemplateMapper.selectProjectIdsByTemplateId(msgTemplateDO.getId()));
        }
        return list;
    }

    private String render(String tpl, Map<String, Object> vars) {
        if (tpl == null) return "";
        String s = tpl;
        if (vars != null) {
            for (Map.Entry<String, Object> e : vars.entrySet()) {
                String key = e.getKey();
                Object val = e.getValue();
                s = s.replace("{" + key + "}", val == null ? "" : String.valueOf(val));
            }
        }
        return s;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteTemplate(Long id) {
        if (id == null) {
            throw new ServiceException("模板ID不能为空");
        }

        // 1. 检查模板是否存在
        MsgTemplateDO template = getById(id);
        if (template == null) {
            throw new ServiceException("模板不存在");
        }

        // 2. 检查是否被项目绑定使用
        List<Long> projectIds = projectMsgTemplateMapper.selectProjectIdsByTemplateId(id);
        if (!projectIds.isEmpty()) {
            throw new ServiceException("模板正在被项目使用，无法删除。绑定的项目数量：" + projectIds.size());
        }

        // 3. 检查是否被消息推送任务使用
        LambdaQueryWrapper<MsgPushTaskDO> taskWrapper = new LambdaQueryWrapper<>();
        taskWrapper.eq(MsgPushTaskDO::getTemplateId, id)
                .eq(MsgPushTaskDO::getIsDeleted, 0);
        long taskCount = msgPushTaskMapper.selectCount(taskWrapper);
        if (taskCount > 0) {
            throw new ServiceException("模板正在被消息推送任务使用，无法删除。关联的任务数量：" + taskCount);
        }

        // 4. 执行逻辑删除
        return removeById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteTemplates(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            throw new ServiceException("模板ID列表不能为空");
        }

        // 逐个检查并删除
        for (Long id : ids) {
            deleteTemplate(id);
        }

        return true;
    }
}
